/**
 * rc522模块库，支持读取各种卡序列号，但只支持读写 M1 卡。
*/

#ifndef _RC522_H_
#define _RC522_H_

#include <stdint.h>
#include <stdbool.h>

typedef enum {
	RC522_OK, // 成功
	RC522_NOTAG, // 无卡
	RC522_UNSUPPORT_TAGTYPE, // 不支持的卡类型
	RC522_ANTICOLL_FAIL, // 防重叠失败
	RC522_SELECT_FAIL, // 选卡失败
	RC522_AUTH_FAIL, // 验证失败
	RC522_READ_FAIL, // 读取失败
	RC522_WRITE_FAIL, // 写入失败
	RC522_ADDR_OUT_OF_RANGE, // 地址超出范围
} rc522_err_t;

struct rc522_tag {
	/**
         * tag_type
         * 
         * 0x4400 = Mifare_UltraLight
         * 0x0400 = Mifare_One(S50)
         * 0x0200 = Mifare_One(S70)
         * 0x0800 = Mifare_Pro(X)
         * 0x4403 = Mifare_DESFire
         * 
        */
	uint8_t tag_type[2];

	uint8_t tag_serial_num[4];
};

bool rc522_tag_eq(struct rc522_tag *tag1, struct rc522_tag *tag2);

void rc522_init(void);

void rc522_free(void);

/**
 * @brief 扫描一次获取卡信息
 * @param tag 存放卡信息
 * @return 错误值
 */
rc522_err_t rc522_scan(struct rc522_tag *tag);

/**
 * @brief 读取卡
 * @param tag 卡信息，提供序列号
 * @param key_A 密钥A
 * @param addr 地址
 * @param data[16] 存放读取到的数据
 * @return 错误值
 */
rc522_err_t rc522_read(const struct rc522_tag *tag, const uint8_t key_A[6],
		       uint8_t addr, uint8_t data[16]);

/**
 * @brief 写入卡
 * @param tag 卡信息，提供序列号
 * @param key_A 密钥A
 * @param addr 地址
 * @param data[16] 欲写入的数据
 * @return 错误值
 */
rc522_err_t rc522_write(const struct rc522_tag *tag, const uint8_t key_A[6],
			uint8_t addr, const uint8_t data[16]);

/**
 * @brief 读取任意卡
 * @param tag 卡信息，存放序列号
 * @param key_A 密钥A
 * @param addr 地址
 * @param data[16] 存放读取到的数据
 * @return 错误值
 */
rc522_err_t rc522_read_any(struct rc522_tag *tag, const uint8_t key_A[6],
			   uint8_t addr, uint8_t data[16]);

/**
 * @brief 写入任意卡
 * @param tag 卡信息，存放序列号
 * @param key_A 密钥A
 * @param addr 地址
 * @param data[16] 欲写入的数据
 * @return 错误值
 */
rc522_err_t rc522_write_any(struct rc522_tag *tag, const uint8_t key_A[6],
			    uint8_t addr, const uint8_t data[16]);

#endif